package com.tbit.uqbike.service.business.impl;

import com.tbit.uqbike.object.pojo.Machine;
import com.tbit.uqbike.object.pojo.vo.ForceFinishSumVO;
import com.tbit.uqbike.object.pojo.vo.ForceFinishVO;
import com.tbit.common.entity.view.PageResult;
import com.tbit.common.entity.view.Result;
import com.tbit.uqbike.service.business.ForceFinishService;
import com.tbit.uqbike.webmanager.dao.core.MachineDao;
import com.tbit.uqbike.webmanager.dao.log.ForceFinishDao;
import com.tbit.utils.DateTimeUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author yee_
 * @version 1.0
 * @date 2023/4/21 14:57
 */
@Service
public class ForceFinishServiceImpl implements ForceFinishService {

    @Resource
    private ForceFinishDao forceFinishDao;
    @Resource
    private MachineDao machineDao;

    @Override
    public Result<PageResult<ForceFinishVO>> listPage(Integer accountId, String orderNo, String phone,
                                                      String machineNo, Long startTime, Long endTime,
                                                      Integer page, Integer size) {
        Integer machineId = null;
        if (StringUtils.isNotBlank(machineNo)) {
            Machine machine = machineDao.getByMachineNO(machineNo);
            if (machine == null) {
                return Result.success(
                        new PageResult<>(page, size, 0L, 0, Collections.emptyList())
                );
            }
            machineId = machine.getMachineId();
        }
        Map<String, Object> paramMap = new HashMap<>(16);
        paramMap.put("machineId", machineId);
        paramMap.put("accountId", accountId);
        paramMap.put("orderNo", orderNo);
        paramMap.put("phone", phone);
        paramMap.put("startTime", Optional.ofNullable(startTime).map(x -> DateTimeUtil.DateTimeToString(new Date(x))).orElse(null));
        paramMap.put("endTime", Optional.ofNullable(endTime).map(x -> DateTimeUtil.DateTimeToString(new Date(x))).orElse(null));
        paramMap.put("page", (page - 1) * size);
        paramMap.put("size", size);
        long pageCount = forceFinishDao.listPageCount(paramMap);
        if (pageCount <= 0) {
            return Result.success(
                    new PageResult<>(page, size, 0L, 0, Collections.emptyList()));
        }
        List<ForceFinishVO> resultList = forceFinishDao.listPage(paramMap);
        replaceMachineNo(resultList);
        return Result.success(
                new PageResult<>(page, size, pageCount,
                        pageCount % size == 0 ? (int) (pageCount / size) : (int) (pageCount / size) + 1,
                        resultList)
        );
    }


    @Override
    public Result<List<ForceFinishVO>> export(Integer accountId, String orderNo, String phone, String machineNo, Long startTime, Long endTime) {
        Integer machineId = null;
        if (StringUtils.isNotBlank(machineNo)) {
            Machine machine = machineDao.getByMachineNO(machineNo);
            if (machine == null) {
                return Result.success(Collections.emptyList());
            }
            machineId = machine.getMachineId();
        }
        Map<String, Object> paramMap = new HashMap<>(16);
        paramMap.put("machineId", machineId);
        paramMap.put("accountId", accountId);
        paramMap.put("orderNo", orderNo);
        paramMap.put("phone", phone);
        paramMap.put("startTime", Optional.ofNullable(startTime).map(x -> DateTimeUtil.DateTimeToString(new Date(x))).orElse(null));
        paramMap.put("endTime", Optional.ofNullable(endTime).map(x -> DateTimeUtil.DateTimeToString(new Date(x))).orElse(null));
        List<ForceFinishVO> resultList = forceFinishDao.listPage(paramMap);
        replaceMachineNo(resultList);
        return Result.success(resultList);
    }


    @Override
    public Result<PageResult<ForceFinishSumVO>> sumBy(Integer accountId, Integer type, Long startTime, Long endTime, Integer page, Integer size) {
        Map<String, Object> paramMap = new HashMap<>(8);
        paramMap.put("accountId", accountId);
        paramMap.put("type", type);
        paramMap.put("endTime", Optional.ofNullable(endTime).map(x -> DateTimeUtil.DateTimeToString(new Date(x))).orElse(null));
        paramMap.put("startTime", Optional.ofNullable(startTime).map(x -> DateTimeUtil.DateTimeToString(new Date(x))).orElse(null));
        paramMap.put("page", (page - 1) * size);
        paramMap.put("size", size);
        long pageCount = forceFinishDao.sumByCount(paramMap);
        if (pageCount <= 0) {
            return Result.success(
                    new PageResult<>(page, size, 0L, 0, Collections.emptyList()));
        }
        List<ForceFinishSumVO> dataList = forceFinishDao.sumBy(paramMap);
        int machineType = 2;
        if (Objects.equals(type, machineType)) {
            dataList.forEach(x -> {
                String machineNo = Optional.ofNullable(x.getColumn())
                        .map(Integer::valueOf)
                        .map(machineDao::getByMachineId)
                        .map(Machine::getMachineNO)
                        .orElse("-");
                x.setColumn(machineNo);
            });
        }
        return Result.success(
                new PageResult<>(page, size, pageCount,
                        pageCount % size == 0 ? (int) (pageCount / size) : (int) (pageCount / size) + 1,
                        dataList)
        );
    }

    private void replaceMachineNo(List<ForceFinishVO> resultList) {
        Map<String, String> machineNoCacheMap = new HashMap<>(1024);
        resultList.forEach(x -> {
            String machineNo = machineNoCacheMap.get(x.getMachineNo());
            if (StringUtils.isBlank(machineNo)) {
                machineNo = Optional.ofNullable(machineDao.getByMachineId(Integer.valueOf(x.getMachineNo()))).map(Machine::getMachineNO).orElse("-");
                machineNoCacheMap.put(x.getMachineNo(), machineNo);
            }
            x.setMachineNo(machineNo);
        });
    }

}
